package com.sky.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sky.context.ThreadLocalUtil;
import com.sky.dto.*;
import com.sky.entity.*;
import com.sky.exception.BusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.webSocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    AddressBookMapper addressBookMapper;
    @Autowired
    ShoppingCartMapper shoppingCartMapper;
    @Autowired
    OrderDetailMapper orderDetailMapper;
    @Autowired
    WebSocketServer webSocketServer;

    @Override
    @Transactional
    public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) {
        Long userId = ThreadLocalUtil.getCurrentId();

        //1、保存订单
        //-DTO拷贝到PO
        Orders orders = BeanUtil.copyProperties(ordersSubmitDTO, Orders.class);
        //-补全数据
        orders.setNumber(RandomUtil.randomNumbers(9));//随机生成一个九位数订单号
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setUserId(userId);
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(Orders.UN_PAID);
        //-根据地址查询id查询地址薄
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if (addressBook == null) {
            throw new BusinessException(500, "收货地址错误");
        }

        //-补全地址信息
        orders.setPhone(addressBook.getPhone());
        orders.setAddress(addressBook.getDetail());
        orders.setConsignee(addressBook.getConsignee());
        //-insert保存订单
        orderMapper.insert(orders);
        //2、保存订单明细
        //-查询当前登录人的购物车列表
        List<ShoppingCart> cartList = shoppingCartMapper.getByUserId(userId);
        if (cartList.size() < 1) {
            throw new BusinessException(500, "购物车还没选择商品");
        }

        //-遍历购物车列表
        for (ShoppingCart shoppingCart : cartList) {
            //*拷贝购物车到订单明细对象，忽略id不拷贝
            OrderDetail orderDetail = BeanUtil.copyProperties(shoppingCart, OrderDetail.class, "id");
            //*设置订单id
            orderDetail.setOrderId(orders.getId());
            //*保存订单明细
            orderDetailMapper.insert(orderDetail);
        }


        //3、清空购物车

        shoppingCartMapper.clean(userId);
        //4、返回VO
        OrderSubmitVO VO = OrderSubmitVO.builder()
                .orderAmount(orders.getAmount())
                .orderNumber(orders.getNumber())
                .id(orders.getId())
                .orderTime(orders.getOrderTime())
                .build();
        return VO;
    }

    /**
     * 历史订单
     * @param page
     * @param pageSize
     * @param status
     * @return
     */
    @Override
    public PageResult page4app(Integer page, Integer pageSize, Integer status) {
        //1、开启分页
        PageHelper.startPage(page, pageSize);
        //2、查询-通过对象封装查询参数
        //封装查询参数的对象,
        OrdersPageQueryDTO queryDTO = OrdersPageQueryDTO.builder()
                .status(status)//根据订单的状态查询，
                .userId(ThreadLocalUtil.getCurrentId())//查当前用户的订单
                .build();
        //调用mapper查询
        List<Orders> list=orderMapper.list(queryDTO);
        //封装结果
        PageInfo<Orders> pageInfo = new PageInfo<>(list);
        List<Orders> pageDate = pageInfo.getList();//当前这一页的数据
        //List<Orders>转List<OrdersVO>
        List<OrderVO> orderVOList = BeanUtil.copyToList(pageDate, OrderVO.class);
        //遍历vo集合，查询每个订单的订单明细
        for (OrderVO orderVO : orderVOList) {
            //根据orderId查询orderDetail
            List<OrderDetail> orderDetails=orderDetailMapper.getByOrderId(orderVO.getId());
            //设置订单明细到vo中
            orderVO.setOrderDetailList(orderDetails);
        }
        //返回自定义分页对象
        PageResult pageResult = new PageResult(pageInfo.getTotal(),orderVOList);
        return pageResult;



    }

    /**
     * 订单详情
     * @param orderId
     * @return
     */
    @Override
    public OrderVO orderDetail(Long orderId) {
        //1、根据id查询订单
       Orders orders=orderMapper.getById(orderId);//返回的是订单
        //2、根据id查询订单明细
        List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(orderId);
        //3、封装vo
        OrderVO vo = BeanUtil.copyProperties(orders, OrderVO.class);//把orders拷贝成orderVO
        vo.setOrderDetailList(orderDetails);

        //4、返回
        return vo;
    }

    /**
     * 取消订单
     * @param orderId
     */
    @Override
    public void cancel(Long orderId) {
        //1、根据orderid查询订单
        Orders orders = orderMapper.getById(orderId);
        if (orders==null){//订单里啥也没有
            return;
        }
        //2、判断订单状态>2抛出异常
        if (orders.getStatus()>2){//抛出异常
            throw new BusinessException(500,"订单正在派送请联系商家取消订单");
        }
        //3、取消订单
        //3.1、新建一个updateOrders，设置id，status,取消原因，取消时间
        Orders updateOrders = Orders.builder()
                .id(orderId)
                .status(Orders.CANCELLED)
                .cancelReason("用户取消订单 ")
                .cancelTime(LocalDateTime.now())
                .build();
        //4、判断status==2
        if (orders.getStatus()==Orders.TO_BE_CONFIRMED){
            System.out.println("退款成功，请在付款账户查收");//退款
        }
        //updateOrders（已退款）
        updateOrders.setPayStatus(Orders.REFUND);//0未支付 1已支付  2已退款
        //调用mapper修改updateOrder
        orderMapper.update(updateOrders);
    }

    /**
     * 再来一单
     * @param orderId
     */
    @Override
    public void repetition(Long orderId) {
        //1、根据订单id查询订单明细
        List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(orderId);
        if (orderDetails.size()<1){
            return;
        }
        //准备一个shoppingCartList
        ArrayList<ShoppingCart> cartList = new ArrayList<>();
        //2、遍历订单明细集合
        for (OrderDetail orderDetail : orderDetails) {
            //2.1把orerDtail转Shoppingcart
            ShoppingCart shoppingCart = BeanUtil.copyProperties(orderDetail, ShoppingCart.class, "id");
            shoppingCart.setUserId(ThreadLocalUtil.getCurrentId());
            shoppingCart.setCreateTime(LocalDateTime.now());
            //2.2把shoppingCart放入cartList
            cartList.add(shoppingCart);
        }
        //批量保存cartList
        shoppingCartMapper.batchInsert(cartList);
    }


    /**
     * 订单搜索
     * @param ordersPageQueryDTO
     * @return
     */
    @Override
    public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {
        //1、开启分页
        PageHelper.startPage(ordersPageQueryDTO.getPage(),ordersPageQueryDTO.getPageSize());
        //2、查询
        List<Orders> ordersList = orderMapper.list(ordersPageQueryDTO);
        //3、封装分页结果
        PageInfo<Orders> pageInfo = new PageInfo<>(ordersList);
        //4、取当前页数据List<Orders>
        List<Orders> list = pageInfo.getList();
        //5、List<Orders>转List<OrderVO>
        List<OrderVO> orderVOList = BeanUtil.copyToList(list, OrderVO.class);
        //6、遍历List<OrderVO>
        //得到List<orderDetail>
        for (OrderVO orderVO : orderVOList) {
            List<OrderDetail> detailList = orderDetailMapper.getByOrderId(orderVO.getId());
            //遍历List<orderDetail>拼接菜品字符串
            StringBuilder sb = new StringBuilder();
            for (OrderDetail orderDetail : detailList) {
                sb.append(orderDetail.getName()+"*"+orderDetail.getNumber()+"; ");
            }
            //去掉多余的分号
            String substring = sb.substring(0, sb.length() - 2);
            //把菜品字符串设置给orderVO
            orderVO.setOrderDishes(substring.toString());

        }
        PageResult pageResult = new PageResult(pageInfo.getTotal(),pageInfo.getList());

        return pageResult;
    }

    /**
     * 各个状态的订单数量统计
     * @return
     */
    @Override
    public OrderStatisticsVO statistics() {
        //根据状态分别查出待接单，待派送，派送中的订单数量
        Integer toBeConfirm=orderMapper.countByStatus(Orders.TO_BE_CONFIRMED);//待接单
        Integer confirmed=orderMapper.countByStatus(Orders.CONFIRMED);//待配送
        Integer deliveryInProgress=orderMapper.countByStatus(Orders.DELIVERY_IN_PROGRESS);//派送中
        //查询数据封装到OrderStatisticsVO中
        OrderStatisticsVO statisticsVO = OrderStatisticsVO.builder()
                .toBeConfirmed(toBeConfirm)
                .confirmed(confirmed)
                .deliveryInProgress(deliveryInProgress)
                .build();
        return statisticsVO;
    }

    /**
     * 接单
     * @param ordersConfirmDTO
     */
    @Override
    public void confirm(OrdersConfirmDTO ordersConfirmDTO) {
        Orders orders = Orders.builder()
                .id(ordersConfirmDTO.getId())
                .status(Orders.CONFIRMED)
                .build();
        orderMapper.update(orders);
    }

    /**
     * 拒单
     * @param ordersRejectionDTO
     */
    @Override
    public void reject(OrdersRejectionDTO ordersRejectionDTO) {
        //根据id查询订单
        Orders orders  = orderMapper.getById(ordersRejectionDTO.getId());
        //订单状态只有为2(待接单)才能取消订单
        if (orders ==null || !orders.getStatus().equals(Orders.TO_BE_CONFIRMED)){
            throw new BusinessException(500,"订单状态错误");
        }
        //根据id更新订单状态、拒单原因、取消时间
        Orders updateOrders = Orders.builder()
                .id(ordersRejectionDTO.getId())
                .status(Orders.CANCELLED)
                .rejectionReason(ordersRejectionDTO.getRejectionReason())
                .cancelTime(LocalDateTime.now())
                .build();
        //判断支付状态
        if (orders.getPayStatus()==Orders.PAID){
            //退款
            System.out.println("退款成功");
        }
        //修改orders支付状态
        updateOrders.setPayStatus(Orders.REFUND);//支付状态 2.已退款  0.未付款 1.已付款
        //
        orderMapper.update(updateOrders);
    }

    /**
     * 用户催单
     *
     * @param id
     * @return
     */
    public Orders reminder(Long id) {
        // 查询订单是否存在
        Orders orders = orderMapper.getById(id);
        if (orders == null) {
            throw new BusinessException(500,"订单不存在");
        }

        //基于WebSocket实现催单
        Map map = new HashMap();
        map.put("type", 2);//2代表用户催单
        map.put("orderId", id);
        map.put("content", "订单号：" + orders.getNumber());
        webSocketServer.sendToAllClient(JSON.toJSONString(map));
        return orders;
    }


}

